<!--
 * @Description  : 
 * @Version      : 1.0
 * @Author       : seraph
 * @Date         : 2024-12-26 12:19:10
 * @LastEditors  : seraph
 * @LastEditTime : 2025-02-07 12:38:58
-->
<template>
  <h3>Class 与 Style 绑定</h3>
  <p>
    数据绑定的一个常见需求场景是操纵元素的 CSS class 列表和内联样式。因为 class 和 style 都是
    attribute，我们可以和其他 attribute 一样使用 v-bind
    将它们和动态的字符串绑定。但是，在处理比较复杂的绑定时，通过拼接生成字符串是麻烦且易出错的。因此，Vue
    专门为 class 和 style 的 v-bind 用法提供了特
    殊的功能增强。除了字符串外，表达式的值也可以是对象或数组。
  </p>
  <hr />
  <h3>绑定内联样式</h3>
  <h4>绑定对象​</h4>
  <p>:style 支持绑定 JavaScript 对象值，对应的是 HTML 元素的 style 属性：</p>
  <pre><code class="javascript" v-html="highlighted(rawCode01, 'javascript')"></code></pre>
  <pre><code class="html" v-html="highlighted(rawCode02, 'html')"></code></pre>
  <p>尽管推荐使用 camelCase，但 :style 也支持 kebab-cased 形式的 CSS 属性 key (对应其 CSS 中的实际名称)，例如：</p>
  <pre><code class="html" v-html="highlighted(rawCode03, 'html')"></code></pre>
  <p>直接绑定一个样式对象通常是一个好主意，这样可以使模板更加简洁：</p>
  <pre><code class="javascript" v-html="highlighted(rawCode04, 'javascript')"></code></pre>
  <pre><code class="html" v-html="highlighted(rawCode05, 'html')"></code></pre>
  <p>同样的，如果样式对象需要更复杂的逻辑，也可以使用返回样式对象的计算属性。</p>

  <h4>绑定数组</h4>
  <p>我们还可以给 :style 绑定一个包含多个样式对象的数组。这些对象会被合并后渲染到同一元素上：</p>
  <pre><code class="html" v-html="highlighted(rawCode06, 'html')"></code></pre>

  <h4>自动前缀</h4>
  <p>当你在 :style 中使用了需要浏览器特殊前缀的 CSS 属性时，Vue 会自动为他们加上相应的前缀。Vue
    是在运行时检查该属性是否支持在当前浏览器中使用。如果浏览器不支持某个属性，那么将尝试加上各个浏览器特殊前缀，以找到哪一个是被支持的。</p>

  <h4>样式多值</h4>
  <p>你可以对一个样式属性提供多个 (不同前缀的) 值，举例来说：</p>
  <pre><code class="html" v-html="highlighted(rawCode07, 'html')"></code></pre>
  <p>多个值必须用数组的形式传入。数组仅会渲染浏览器支持的最后一个值。在这个示例中，在支持不需要特别前缀的浏览器中都会渲染为 display: flex。</p>
</template>

<script lang="ts" setup>
import { ref, reactive, onMounted, computed } from 'vue'
import hljs from 'highlight.js'
import 'highlight.js/styles/atom-one-dark.css'
import javascript from 'highlight.js/lib/languages/javascript'
import html from 'highlight.js/lib/languages/xml'
import { isatty } from 'tty'
import { on } from 'events'

import MyComponent1 from '@/components/MyComponent1.vue'

hljs.registerLanguage('javascript', javascript)
hljs.registerLanguage('html', html)

const highlighted = (rawCode: string, type: string) => {
  const highlightedCode = hljs.highlight(rawCode, { language: type }).value
  return highlightedCode.replace(/&amp;lt;/g, '&lt;').replace(/&amp;gt;/g, '&gt;')
}

const rawCode01 = `const activeColor = ref('red')
const fontSize = ref(30)`

const rawCode02 = `<div :style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>`

const rawCode03 = `<div :style="{ 'font-size': fontSize + 'px' }"></div>`

const rawCode04 = `const styleObject = reactive({
  color: 'red',
  fontSize: '30px'
})`

const rawCode05 = `<div :style="styleObject"></div>`

const rawCode06 = `<div :style="[baseStyles, overridingStyles]"></div>`

const rawCode07 = `<div :style="{ display: ['-webkit-box', '-ms-flexbox', 'flex'] }"></div>`
</script>

<style scoped>
p {
  font-size: 16px;
  padding: 2px;
  margin: 5px 0;
}

/* 设置预格式化文本的样式 */
pre {
  /* 背景色 */
  background-color: #f1ffed;
  /* 边框 */
  border: 1px solid #ccc;
  /* 缩小内边距 */
  padding: 5px 5px 5px 10px;
  /* 允许滚动 */
  overflow: auto;
  /* 可选：设置上下外边距 */
  margin: 0px 0;
  /* 允许换行 */
  /* normal: 连续的空白字符会被合并为一个空格。文本会在允许的断点处自动换行。
     nowrap：连续的空白字符会被合并为一个空格。文本不会自动换行，即使在允许的断点处也不会换行。
     pre：保留所有的空白字符（包括空格、制表符和换行符）。文本只会在遇到换行符或者 <br> 标签时换行。
     pre-wrap：保留所有的空白字符。文本会在遇到换行符、<br> 标签，或者达到容器边界时换行。
     pre-line：合并连续的空白字符为一个空格，但保留换行符。文本会在遇到换行符、<br> 标签，或者达到容器边界时换行。
   */
  white-space: pre-wrap;
  /* 行高 */
  line-height: 120%;
  /* 定义缩进 */
  tab-size: 4;
}

h3,
h4,
h5,
h6 {
  margin: 25px 0 10px 0;
  line-height: 100%;
}

.bolder {
  font-weight: bolder;
}

.red {
  color: red;
}

button {
  margin: 5px 5px 5px 10px;
  line-height: 150%;
  width: auto;
  padding: 0 10px;
}

.active {
  color: red;
}

.static {
  font-weight: bolder;
}

.text-danger {
  font-style: italic;
}
</style>
